#include "test_config_Den_Lib.h"

#ifdef TEST_DENIS_TARG

#include "Den_Lib/Den_TArg.h"

#define  TEST_DENIS_TARG1
#define  TEST_DENIS_TARG2
#define  TEST_DENIS_TARG3
#define  TEST_DENIS_TARG4

namespace
{
    void Endl()       { FOR_TESTING(std::cout<< endl);        }
    void DebugMsg()   { FOR_TESTING(std::cout<<"DEBUG:\n");   }
    void ReleaseMsg() { FOR_TESTING(std::cout<<"RELEASE:\n"); }
    
    int Foo(){ return int(10); }
    struct Crolik
    {
        Crolik(const Crolik& src):mVal(1){ FOR_TESTING(std::cout<<"Crolik::COPY\n"); }
        Crolik(const int val=0):mVal(1)
        {
            if(val==0) { FOR_TESTING(std::cout<<"Crolik::CTOR\n"); }
            else { FOR_TESTING(std::cout<<" TEMPORARY Crolik::CTOR\n"); }
        }

        ~Crolik(){ FOR_TESTING(std::cout<<"Crolik::DTOR\n"); mVal=0; }
        int mVal;
    };
    Crolik FooCrol(){ return Crolik(); }
}//namespace

#ifdef TEST_DENIS_TARG1

TEST(test_TArg, 000)
{
    TArg<>::DebugType();
    TArg<int>::DebugType();
    TArg<int,int>::DebugType();
    TArg<int,int,int>::DebugType();
    TArg<int,int,int,int>::DebugType();
    TArg<int,int,int,int,int>::DebugType();
    TArg<int,int,int,int,int,int>::DebugType();
    TArg<int,int,int,int,int,int,int>::DebugType();
}

TEST(test_TArg, 001)
{
    TArg<>::DebugType();
    TArg<float>::DebugType();
    TArg<float,float>::DebugType();
    TArg<float,int,float>::DebugType();
    TArg<float,int,int,float>::DebugType();
    TArg<float,int,float,int,float>::DebugType();
    TArg<float,int,float,int,int,float>::DebugType();
    TArg<float,int,int,float,int,int,float>::DebugType();
}

TEST(test_TArg, 003){ TArg<> arg; }

TEST(test_TArg, 004)
{
    TArg<int> arg(10); EXPECT_EQ(10, arg.mArg1 );
}

TEST(test_TArg, 005)
{
    TArg<int, float> arg(10,20); 
    EXPECT_EQ(10, arg.mArg1 );
    EXPECT_EQ(20.0f, arg.mArg2 );
    EXPECT_EQ(20, arg.mArg2 );
}

TEST(test_TArg, 006)
{
    TArg<int, char*> arg(10,"kzkz"); 
    EXPECT_EQ(10, arg.mArg1 );
    EXPECT_EQ("kzkz", arg.mArg2 );
}
#endif

#ifdef TEST_DENIS_TARG2
TEST(test_TArg, 007)
{
    Endl();
    FOR_TESTING(cout<<"BEGIN TEST\n");
    TArg<Crolik> arg( FooCrol() ); arg.DebugType();
    FOR_TESTING(cout<<"ENDED TEST\n");
    EXPECT_EQ(1, arg.mArg1.mVal );
}
TEST(test_TArg, 008)
{
    Endl();
    FOR_TESTING(cout<<"BEGIN TEST\n");
    Crolik crol;
    TArg<Crolik> arg(crol); arg.DebugType();
    FOR_TESTING(cout<<"ENDED TEST\n");
    EXPECT_EQ(1, arg.mArg1.mVal );
}
TEST(test_TArg, 009)
{
    Endl();
    FOR_TESTING(cout<<"BEGIN TEST\n");
    TArg<int,float> arg(10,10.0f); arg.DebugType(); 
    FOR_TESTING(cout<<"ENDED TEST\n");
    EXPECT_EQ(10, arg.mArg1 );
}
TEST(test_TArg, 010)
{
    Endl();
    FOR_TESTING(cout<<"BEGIN TEST\n");
    TArg<int,float> arg(10,10.0f); arg.DebugType(); 
    TArg<int,float> arg1 = arg;
    FOR_TESTING(cout<<"ENDED TEST\n");
    EXPECT_EQ(10, arg.mArg1 );
    EXPECT_EQ(10, arg1.mArg1 );
}
#endif
#ifdef TEST_DENIS_TARG3
TEST(test_TArg, 011)
{
    Endl(); FOR_TESTING(cout<<"BEGIN TEST\n");
    Crolik* pCrol = new Crolik();
    TArg<Crolik> arg(*pCrol); arg.DebugType(); 
    TArg<Crolik> arg1 = arg;
    delete pCrol;
    FOR_TESTING(cout<<"ENDED TEST\n");
    EXPECT_EQ(1, arg.mArg1.mVal );
    EXPECT_EQ(1, arg1.mArg1.mVal );
}
#endif

#ifdef TEST_DENIS_TARG4
TEST(test_TArg, 012)
{
    Endl(); FOR_TESTING(cout<<"BEGIN TEST\n");
    Crolik* pCrol = new Crolik();
    TArg<Crolik,Crolik,Crolik> arg(*pCrol,*pCrol,*pCrol); arg.DebugType();  delete pCrol;
    FOR_TESTING(cout<<"ENDED TEST\n");

    int res = arg.mArg1.mVal + arg.mArg2.mVal +arg.mArg3.mVal;
    EXPECT_EQ(3, res );
}
#endif



#endif //TEST_DENIS_TARG